package com.cloudkinto.service.order.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.bo.order.OrderShopifyQueryBo;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.BizExceptionI18;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.*;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.order.OrderShopifyService;
import com.cloudkinto.service.order.vo.OrderShopifyEntity;
import com.cloudkinto.service.order.vo.amazon.UpdateSysMemoReq;
import com.cloudkinto.service.order.vo.shopify.*;
import com.cloudkinto.service.orderoutput.OrderOutputService;
import com.cloudkinto.service.orderoutput.impl.OrderOutputServiceImpl;
import com.cloudkinto.service.orderoutput.vo.OrderOutputAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputPackageAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputProductAddReq;
import com.cloudkinto.service.product.ProductCombinationService;
import com.cloudkinto.service.product.ProductInfoService;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import com.cloudkinto.service.stock.StockRecordService;
import lombok.RequiredArgsConstructor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author ding
 * @since 2021-09-23
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class OrderShopifyServiceImpl extends ServiceImpl<OrderShopifyDao, OrderShopifyDo> implements OrderShopifyService {
    @Autowired
    private OrderShopifyDao dao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private OrderShopifyProductDao productDao;
    @Autowired
    private OrderShopifyProductDao orderShopifyProductDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private JpRegionService mRegionService;
    @Autowired
    private StockRecordDao stockDao;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private ShipPriceService shipPriceService;
    @Autowired
    private ProductSkuMapDao productSkuMapDao;
    @Autowired
    private OrderOutputService outputService;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private OrderShopifyShippingLinesDao shippingLinesDao;
    @Autowired
    private ProductCombinationService productCombinationService;
    @Autowired
    private StockRecordService stockRecordService;


    @Override
    public SingleResult addInit() {
        return SingleResult.success("");
    }

    @Override
    public Object add(Object req, Long userId) {
        OrderShopifyDo entityDo = new OrderShopifyDo();
        BeanUtils.copyProperties(req, entityDo);
        handlerAddBefore(entityDo, userId);
        dao.insert(entityDo);
        return handlerAddAfter(entityDo);
    }

    //新增校验
    private void addCheck(Object req) {

    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderShopifyDo entityDo, Long userId) {
//        entityDo.setCreateBy(userId);
//        entityDo.setCreateTime(new Date());
//        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(OrderShopifyDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success("");
    }

    @Override
    public Object update(Object req, Long userId) {
        /*OrderShopifyDo entityDo = dao.selectById(req.getId());
        BeanUtils.copyProperties(req, entityDo);
        handlerUpdateBefore(entityDo, userId);
        dao.updateById(entityDo);
        return handlerUpdateAfter(entityDo);*/
        return null;
    }

    //编辑校验
    private void updateCheck(Object req) {

    }

    @Override
    public SingleResult sync(Long shopId, String startDate, String endDate) {
        ShopDo shopDo = shopDao.selectById(shopId);
        long lastId = 0;
        if (shopDo == null) {
            throw new BizExceptionI18(SysConstant.NO_SHOP_INFO);
        }
//        int count = getOrderCount(shopDo, startDate, endDate);
        String url = "https://" + shopDo.getShopifyHost() + "/admin/api/2022-10/orders.json?status=any";
        Map<String, String> bodyMap = null;
        List<String> orderFiledIds = new ArrayList<>();

        do {
            if (bodyMap != null) {
                url = bodyMap.get("page");
            }
            startDate = TimeUtils.addDaysFormat(startDate, "yyyy-MM-dd HH:mm:ss", 0);
            endDate = TimeUtils.addDaysFormat(endDate, "yyyy-MM-dd HH:mm:ss", 1);
            bodyMap = httpGet(url, shopDo, startDate, endDate);
            JSONArray jsonArray = JSONObject.parseObject(bodyMap.get("body")).getJSONArray("orders");
            List<OrderShopifyEntity> orderShopifyEntities = JSON.parseArray(jsonArray.toJSONString(), OrderShopifyEntity.class);
            orderFiledIds.addAll(handlerSyncAfter(orderShopifyEntities, shopDo));
        } while (bodyMap != null && StringUtils.isNotBlank(bodyMap.get("page")));
//        String[] stringIds = new String[]{};
//        orderFiledIds.toArray(stringIds);
//        sendOut(stringIds, 338L, shopDo.getCompanyId(), true);

        return SingleResult.success();
    }

    private Map httpGet(String url, ShopDo shopDo, String startDate, String endDate) {
        Map<String, String> map = new HashMap<>();
        OkHttpClient.Builder client = OkHttpUtils.getUnsafeOkHttpClient().newBuilder();
        client.connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true);
        Map<String, String> params = new HashMap<>();
        String parseStartDate;
        String parseEndDate;
        if (!url.contains("page_info")) {
            //传格林威治时区时间
            if (startDate != null) {
                parseStartDate = TimeUtils.formatDate(TimeUtils.parseDate(startDate, "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd'T'HH:mm:ss", "GMT");
                url = url + "&created_at_min=" + parseStartDate;
            }
            if (endDate != null) {
                parseEndDate = TimeUtils.formatDate(TimeUtils.parseDate(endDate, "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd'T'HH:mm:ss", "GMT");
                url = url + "&created_at_max=" + parseEndDate;
            }
            url = url + "&limit=" + 200;
        }
        Request request = new Request.Builder()
                .addHeader("Content-Type", "application/json;charset=utf-8")
                .addHeader("X-Shopify-Access-Token", shopDo.getShopifyToken())
                .url(url)
                .get()
                .build();
        Response response;
        String body;
        try {
            response = client.build().newCall(request).execute();
            body = response.body().string();
            System.out.println(body);
            map.put("body", body);
            map.put("page", getNextpage(response.header("Link")));
            return map;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getNextpage(String link) {
        if (StringUtils.isBlank(link)) {
            return link;
        }
        String[] strings = link.replaceAll("<", "").replaceAll(">", "").split(",");
        for (String string : strings) {
            String[] split = string.split(";");
            String url = split[0];
            String type = split[1];
            if (type.contains("next")) {
                return url;
            }
        }
        return null;
    }

    private List<String> handlerSyncAfter(List<OrderShopifyEntity> orderShopifyEntities, ShopDo shopDo) {
        List<String> insertIds = new ArrayList<>();

        orderShopifyEntities.stream().forEach(orderShopifyEntity -> {
            LambdaQueryWrapper<OrderShopifyDo> orderShopifyDoWrapper = new LambdaQueryWrapper<>();
            orderShopifyDoWrapper.eq(OrderShopifyDo::getOrderId, orderShopifyEntity.getId());
            OrderShopifyDo shopifyDo = dao.selectOne(orderShopifyDoWrapper);
            if (shopifyDo == null) {
                shopifyDo = new OrderShopifyDo();
            }
            if (shopDo == null) {
                shopifyDo.setCompanyId(1L);
                shopifyDo.setShopId(33L);
            } else {
                shopifyDo.setCompanyId(shopDo.getCompanyId());
                shopifyDo.setShopId(shopDo.getId());
            }
            shopifyDo.setOrderNumber(orderShopifyEntity.getOrder_number());
            shopifyDo.setOrderName(orderShopifyEntity.getName());
            shopifyDo.setOrderId(orderShopifyEntity.getId());
            if (orderShopifyEntity.getPayment_gateway_names() != null && orderShopifyEntity.getPayment_gateway_names().size() > 0) {
                String payments = String.join(",", orderShopifyEntity.getPayment_gateway_names());
                shopifyDo.setPaymentGatewayNames(payments);
            } else {
                shopifyDo.setPaymentGatewayNames(orderShopifyEntity.getGateway());
            }
            shopifyDo.setTotalPrice(orderShopifyEntity.getTotal_price());
            shopifyDo.setSubtotalPrice(orderShopifyEntity.getSubtotal_price());
            shopifyDo.setReference(orderShopifyEntity.getReference());
            shopifyDo.setNumber(orderShopifyEntity.getNumber());
            shopifyDo.setTotalTax(orderShopifyEntity.getTotal_tax());
            shopifyDo.setTotalDiscounts(orderShopifyEntity.getTotal_discounts());
            shopifyDo.setPhone(orderShopifyEntity.getPhone());
            if (orderShopifyEntity.getShipping_address() != null) {
                shopifyDo.setShippingAddress(orderShopifyEntity.getShipping_address().getAddress1() +
                        orderShopifyEntity.getShipping_address().getAddress2());
                shopifyDo.setShippingZip(orderShopifyEntity.getShipping_address().getZip());
                shopifyDo.setShippingCountryCode(orderShopifyEntity.getShipping_address().getCountry_code());
                shopifyDo.setShippingProvince(StringsUtil.getJpAreaByEnglishCode(orderShopifyEntity.getShipping_address().getProvince()));
                shopifyDo.setShippingCity(orderShopifyEntity.getShipping_address().getCity());
                shopifyDo.setShippingPhone(orderShopifyEntity.getShipping_address().getPhone());
                shopifyDo.setShippingName(orderShopifyEntity.getShipping_address().getName());
                shopifyDo.setShippingName((StringUtils.isNotBlank(orderShopifyEntity.getShipping_address().getLast_name()) ? orderShopifyEntity.getShipping_address().getLast_name() : "")
                        + " " + (StringUtils.isNotBlank(orderShopifyEntity.getShipping_address().getFirst_name()) ? orderShopifyEntity.getShipping_address().getFirst_name() : ""));
            }
            shopifyDo.setLocationId(orderShopifyEntity.getLocation_id());
            shopifyDo.setCreatedAt(orderShopifyEntity.getCreated_at());
            shopifyDo.setUpdatedAt(orderShopifyEntity.getUpdated_at());
            shopifyDo.setProcessedAt(orderShopifyEntity.getProcessed_at());
//            shopifyDo.setTaxesIncluded(orderShopifyEntity.getTotal_tax());
//            shopifyDo.setConfirmed(orderShopifyEntity.getClient_details());
            shopifyDo.setContactEmail(orderShopifyEntity.getContact_email());
            shopifyDo.setEmail(orderShopifyEntity.getEmail());
            shopifyDo.setCurrency(orderShopifyEntity.getCurrency());
            if (orderShopifyEntity.getFulfillment_status() == null) {
                shopifyDo.setFulfillmentStatus("unshipped");
            } else {
                shopifyDo.setFulfillmentStatus(orderShopifyEntity.getFulfillment_status());
            }
            shopifyDo.setFinancialStatus(orderShopifyEntity.getFinancial_status());
            if (shopifyDo.getId() == null || shopifyDo.getId() == 0) {
                shopifyDo.setIsSendOut(0);
                shopifyDo.setIsUploadExpress(0);
                save(shopifyDo);
                insertIds.add(shopDo.getId() + "");
            } else {
                updateById(shopifyDo);
            }
            for (OrderShopifyEntity.Line_itemsEntity line_item : orderShopifyEntity.getLine_items()) {
                LambdaQueryWrapper<OrderShopifyProductDo> itemWrapper = new LambdaQueryWrapper<>();
                itemWrapper.eq(OrderShopifyProductDo::getItemId, line_item.getId());
                OrderShopifyProductDo productDo = productDao.selectOne(itemWrapper);
                if (productDo == null) {
                    productDo = new OrderShopifyProductDo();
                }
                productDo.setFulfillableQuantity(line_item.getFulfillable_quantity());
                productDo.setQuantity(line_item.getQuantity());
                productDo.setVariantTitle(line_item.getVariant_title());
                productDo.setTitle(line_item.getTitle());
                productDo.setPrice(line_item.getPrice());
                productDo.setProductId(line_item.getProduct_id());
                productDo.setItemId(line_item.getId());
                productDo.setSku(line_item.getSku());
                productDo.setSkuName(line_item.getName());
                productDo.setOrderId(shopifyDo.getId());
                if (productDo.getId() == null || productDo.getId() == 0) {
                    productDao.insert(productDo);
                } else {
                    productDao.updateById(productDo);
                }
            }
            for (OrderShopifyShippingEntity shopifyShippingEntity : orderShopifyEntity.getShipping_lines()) {
                OrderShopifyShippingLinesDo productDo = shippingLinesDao.selectById(shopifyShippingEntity.getId());
                if (productDo == null || productDo.getId() == null || productDo.getId() == 0) {
                    productDo = new OrderShopifyShippingLinesDo();
                    BeanUtils.copyProperties(shopifyShippingEntity, productDo);
                    productDo.setOrderId(shopifyDo.getId());
                    shippingLinesDao.insert(productDo);
                } else {
                    BeanUtils.copyProperties(shopifyShippingEntity, productDo);
                    productDo.setOrderId(shopifyDo.getId());
                    shippingLinesDao.updateById(productDo);
                }
            }
        });
        return insertIds;
    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderShopifyDo entityDo, Long userId) {
//        entityDo.setUpdateBy(userId);
//        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private Object handlerUpdateAfter(OrderShopifyDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public int delete(Long id, Long userId) {
        OrderShopifyDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderShopifyDo entityDo, Long userId) {
//        entityDo.setDeleteBy(userId);
//        entityDo.setDeleteTime(new Date());
    }

    @Override
    public OrderShopifyRes detail(Long id) {
        OrderShopifyDo entityDo = dao.selectById(id);
        OrderShopifyDetaillRes res = new OrderShopifyDetaillRes();
        res.setSubtotalPrice(entityDo.getSubtotalPrice());
        res.setTotalPrice(entityDo.getTotalPrice());
        BeanUtils.copyProperties(entityDo, res);
        return handlerDetailAfter(res);
    }

    //查询明细之后要执行的业务定制处理
    private OrderShopifyDetaillRes handlerDetailAfter(OrderShopifyDetaillRes res) {
        ShopDo shopDo = shopDao.selectById(res.getShopId());
        res.setFulfillmentStatus(getOrderShipTypeStr(res.getFulfillmentStatus()));
        res.setFinancialStatus(getOrderStatusStr(res.getFinancialStatus()));
        if (shopDo != null) {
            res.setShopName(shopDo.getShopName());
        }
        List<OrderShopifyProductDo> shopifyProductDos = orderShopifyProductDao.selectList(new LambdaQueryWrapper<OrderShopifyProductDo>()
                .eq(OrderShopifyProductDo::getOrderId, res.getId()));
        if (shopifyProductDos.size() > 0) {
            List<String> skuList = shopifyProductDos.stream().map(OrderShopifyProductDo::getSku)
                    .collect(Collectors.toList());
            String sku = StringUtils.join(skuList, ",");
            res.setSku(sku);
        }
        List<OrderShopifyItemRes> orderShopifyItemResList = new ArrayList<>();
        shopifyProductDos.forEach(orderShopifyProductDo -> {
            OrderShopifyItemRes itemRes = new OrderShopifyItemRes();
            BeanUtils.copyProperties(orderShopifyProductDo, itemRes);
            orderShopifyItemResList.add(itemRes);
        });

        //查询日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(res.getId(), 7);
        res.setOperateResList(operateResList);
        res.setItemResList(orderShopifyItemResList);
        return res;
    }

    @Override
    public void exportExcel(OrderShopifyQueryBo bo, HttpServletResponse response) throws Exception {
        List<OrderShopifyDo> OrderShopifyDoList;

        if (CollectionUtils.isEmpty(bo.getIds())) {
            LambdaQueryWrapper<OrderShopifyDo> wrapper = queryBuild(bo);
            OrderShopifyDoList = baseMapper.selectList(wrapper);
        } else {
            LambdaQueryWrapper<OrderShopifyDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(OrderShopifyDo::getId, bo.getIds())
                    .eq(Objects.nonNull(bo.getCompanyId()), OrderShopifyDo::getCompanyId, bo.getCompanyId())
                    .orderByDesc(OrderShopifyDo::getCreatedAt);
            OrderShopifyDoList = baseMapper.selectList(wrapper);
        }
        if (OrderShopifyDoList.size() > 5000) {
            response.sendError(500, "数据超过1000条，请分日期导出");
            throw new BizException(SysConstant.File_Export_ToMuch, 1000);
        }
        List<OrderShopifyResExcelExportVo> excelExportVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(OrderShopifyDoList)) {
//            LambdaQueryWrapper<OrderShopifyProductDo> itemsWrapper;
            for (OrderShopifyDo OrderShopifyDo : OrderShopifyDoList) {
                OrderShopifyResExcelExportVo excelExportVo = new OrderShopifyResExcelExportVo();
                BeanUtils.copyProperties(OrderShopifyDo, excelExportVo);

                /*itemsWrapper = new LambdaQueryWrapper<>();
                itemsWrapper.eq(OrderShopifyProductDo::getOrderId, OrderShopifyDo.getId());
                List<OrderShopifyProductDo> itemsDoList = productDao.selectList(itemsWrapper);

                List<AmazonOrderItemExcelExportVo> itemExcelExportVoList = new ArrayList<>();
                if (!CollectionUtils.isEmpty(itemsDoList)) {
                    for (OrderShopifyProductDo itemsDo : itemsDoList) {
                        AmazonOrderItemExcelExportVo itemExcelExportVo = new AmazonOrderItemExcelExportVo();
                        BeanUtils.copyProperties(itemsDo, itemExcelExportVo);
                        itemExcelExportVoList.add(itemExcelExportVo);
                    }
                }*/

//                excelExportVo.setItemExcelExportVoList(itemExcelExportVoList);

                excelExportVoList.add(excelExportVo);
            }
        }
        ExportParams exportParams = new ExportParams();
        exportParams.setCreateHeadRows(true);
        exportParams.setHeaderColor(IndexedColors.YELLOW.getIndex());
        ExcelUtils.exportExcel(excelExportVoList, OrderShopifyResExcelExportVo.class, "shopify订单", exportParams, response);
    }

    @Override
    public SingleResult markSendOut(List<Long> ids, Long userId) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BizExceptionI18(SysConstant.PLS_CHOOSE_ORDER);
        }
        for (Long id : ids) {
            OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
            if (OrderShopifyDo.getIsSendOut() == 0) {
                OrderShopifyDo.setIsSendOut(1);
                this.baseMapper.updateById(OrderShopifyDo);
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_MARK_SEND, OrderShopifyDo.getId(), userId, 7);
            }
        }
        return SingleResult.success();
    }

//    private void operateRecord(String str, OrderShopifyDo OrderShopifyDo, Long userId) {
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setContent(str);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setType(7);
//        operateRecordDo.setThirdId(OrderShopifyDo.getId());
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDao.insert(operateRecordDo);
//    }

    @Override
    public SingleResult updateSysMemo(UpdateSysMemoReq req, Long userId, Long companyId) {
        OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(req.getId());
        OrderShopifyDo.setSystemMemo(req.getSystemMemo());
        this.baseMapper.updateById(OrderShopifyDo);
        return SingleResult.success("编辑成功", null);
    }

    @Override
    public SingleResult systemMemoInit(Long id) {
        OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
        return SingleResult.success(OrderShopifyDo.getSystemMemo());
    }

    @Override
    public SingleResult sendOut(String[] ids, Long userId, Long companyId, boolean isAuto) {
        sufficientFundsCheck(companyId);
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        List<String> failOrders = new ArrayList<>();
        ll:
        for (String id : ids) {
            List<OrderOutputProductAddReq> itemAddReqList = new ArrayList<>();
            boolean isSetCod = false;
            OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
            if (OrderShopifyDo == null) {
                failOrders.add(StringsUtil.createI18Message(SysConstant.NO_ORDER_INFO_ID) + OrderShopifyDo.getOrderNumber());
                continue;
            }
            if ("Canceled".equals(OrderShopifyDo.getFinancialStatus()) ||
                    "refunded".equals(OrderShopifyDo.getFinancialStatus()) ||
                    "voided".equals(OrderShopifyDo.getFinancialStatus())) {
                failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_HAS_DROP) + OrderShopifyDo.getOrderName());
                continue;
            }
            if (!"unshipped".equals(OrderShopifyDo.getFulfillmentStatus()) && isAuto) {
                failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_STATUS_NO_SEND) + OrderShopifyDo.getOrderName());
                continue;
            }
            LambdaQueryWrapper<OrderShopifyProductDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrderShopifyProductDo::getOrderId, id);
            List<OrderShopifyProductDo> itemsDoList = productDao.selectList(wrapper);
            //订单
            OrderOutputAddReq res = new OrderOutputAddReq();
            res.setOrderType(1);
            if (OrderShopifyDo.getPaymentGatewayNames() != null) {
                if (OrderShopifyDo.getPaymentGatewayNames().contains("代金引換") ||
                        OrderShopifyDo.getPaymentGatewayNames().contains("代金引换") ||
                        OrderShopifyDo.getPaymentGatewayNames().contains("Cash on Delivery (COD)")) {
                    res.setCod((int) OrderShopifyDo.getTotalPrice() + getOtherFee(OrderShopifyDo.getId(), OrderShopifyDo.getTotalPrice()));
                } else if ((!"authorized".equals(OrderShopifyDo.getFinancialStatus()) &&
                        !"partially_refunded".equals(OrderShopifyDo.getFinancialStatus()) &&
                        !"paid".equals(OrderShopifyDo.getFinancialStatus()))) {
                    if (!OrderShopifyDo.getPaymentGatewayNames().contains("B2B")) {
                        System.out.println("B2B 订单不考虑付款");
                        failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_PAYMENT_ID, OrderShopifyDo.getOrderName()));
                        continue;
                    }
                }
            }
            LambdaQueryWrapper<OrderShopifyShippingLinesDo> wrapperShippingLines = new LambdaQueryWrapper<>();
            wrapperShippingLines.eq(OrderShopifyShippingLinesDo::getOrderId, id);
            List<OrderShopifyShippingLinesDo> shippingLinesDos = shippingLinesDao.selectList(wrapperShippingLines);
            if (shippingLinesDos != null && shippingLinesDos.size() > 0) {
                for (OrderShopifyShippingLinesDo shippingLinesDo : shippingLinesDos) {
                    if (shippingLinesDo.getCode() != null) {
                        if (shippingLinesDo.getCode().contains("お急ぎ便")) {
                            res.setShipmentType(1);
                            break;
                        }
                    }
                }
            }
            for (OrderShopifyProductDo productDo : itemsDoList) {
                if (productDo.getSku().contains("+")) {
                    for (String sku : productDo.getSku().split("\\+")) {
                        OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                        Long productId = productInfoService.getProductId(sku, OrderShopifyDo.getCompanyId());
                        if (productId == null) {
                            failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_INFO2_ID, OrderShopifyDo.getOrderNumber(), sku));
                            continue;
                        }
                        productDo1.setProductId(productId);
                        productDo1.setCommoditySku(sku);
                        productDo1.setCount(productDo.getQuantity());
                        itemAddReqList.add(productDo1);
                    }
                } else {
                    ProductInfoDo productInfoDo = productInfoService.getProductDo(productDo.getSku(), OrderShopifyDo.getCompanyId());
                    if (productInfoDo == null) {
                        failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_INFO2_ID, OrderShopifyDo.getOrderNumber(), productDo.getSku()));
                        continue;
                    }
                    if (!productInfoDo.getTypeOfProduct().equals(StaticDict.Product_Info_Type.Combination.getValue())) {
                        OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                        productDo1.setProductId(productInfoDo.getId());
                        productDo1.setCommoditySku(productInfoDo.getCommoditySku());
                        productDo1.setCount(productDo.getQuantity());
                        itemAddReqList.add(productDo1);
                    } else {
                        LambdaQueryWrapper<ProductCombinationDo> productCombinationWrapper = new LambdaQueryWrapper<>();
                        productCombinationWrapper.eq(ProductCombinationDo::getParentId, productInfoDo.getId());
                        List<ProductCombinationDo> productCombinationDoList = productCombinationService.getBaseMapper().selectList(productCombinationWrapper);
                        for (ProductCombinationDo productCombinationDo : productCombinationDoList) {
                            if (productCombinationDo.getEffective() == 1) {
                                if (productCombinationDo.getEffectBeginTime() == null || productCombinationDo.getEffectEndTime() == null)
                                    continue;
                                if (OrderShopifyDo.getCreatedAt().getTime() < productCombinationDo.getEffectBeginTime().getTime()
                                        || OrderShopifyDo.getCreatedAt().getTime() > productCombinationDo.getEffectEndTime().getTime())
                                    continue;
                            }
                            OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                            ProductInfoDo productInfoDo1 = productInfoService.getById(productCombinationDo.getChildId());
                            if (productInfoDo1 == null) {
                                failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_GROUP_INFO_ID, OrderShopifyDo.getOrderNumber(), productInfoDo.getCommoditySku()));
                                continue;
                            }
                            productDo1.setProductId(productCombinationDo.getChildId());
                            productDo1.setCommoditySku(productInfoDo1.getCommoditySku());
                            productDo1.setCount(productDo.getQuantity() * productCombinationDo.getCount());
                            itemAddReqList.add(productDo1);
                        }
                    }
                }
            }
            res.setSendDate(new Date());
            res.setShopId(OrderShopifyDo.getShopId());
            res.setCompanyId(OrderShopifyDo.getCompanyId());
            res.setOrderNo(OrderShopifyDo.getOrderName());
            res.setPlatform("shopify");
            res.setPlatformNumber(OrderShopifyDo.getId() + "");
            res.setReceiverName(OrderShopifyDo.getShippingName());

            res.setTelPhone(OrderShopifyDo.getShippingPhone());
            res.setPostCode(OrderShopifyDo.getShippingZip());
            res.setArea(OrderShopifyDo.getShippingProvince());
            if (org.apache.commons.lang3.StringUtils.isNotBlank(OrderShopifyDo.getShippingCity())) {
                res.setAddress(OrderShopifyDo.getShippingCity() + OrderShopifyDo.getShippingAddress());
            } else {
                res.setAddress(OrderShopifyDo.getShippingAddress());
            }
//            if (OrderShopifyDo.getLastDeliveryDate() != null && OrderShopifyDo.getEarliestDeliveryDate() != null &&
//                    "Scheduled".equals(OrderShopifyDo.getShipmentServiceLevelCategory())) {
//                res.setDeliveryDate(TimeUtils.formatDate(OrderShopifyDo.getLastDeliveryDate()));
//                int time1 = Integer.parseInt(TimeUtils.formatDate(OrderShopifyDo.getEarliestDeliveryDate(), "HH")) + 1;
//                String startTime = time1 < 10 ? "0" + time1 : String.valueOf(time1);
//                int time2 = Integer.parseInt(TimeUtils.formatDate(OrderShopifyDo.getLastDeliveryDate(), "HH")) + 1;
//                String endTime = time2 < 10 ? "0" + time2 : String.valueOf(time2);
//                res.setDeliveryTime(startTime +
//                        "-" + endTime);
//            }
            long storageId = 0L;
            long stateId = 0;
            //item
            List<OrderOutputProductAddReq> orderOutputProductDetailList = new ArrayList<>();
            List<OrderOutputProductAddReq> failedItems = new ArrayList<>();
            if (!CollectionUtils.isEmpty(itemAddReqList)) {
                double[] size = new double[4];
                double shipPirce = 99999D;
                //默认仓库先捆包
                for (OrderOutputProductAddReq itemsDo : itemAddReqList) {
                    Long productId = getProductId(itemsDo.getCommoditySku(), OrderShopifyDo.getCompanyId());
                    if (productId == null) {
                        failedItems.add(itemsDo);
                        failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_INFO2_ID, OrderShopifyDo.getOrderNumber(), itemsDo.getCommoditySku()));
                        continue;
                    }
                    stateId = mRegionService.getStateIdByPostCode(OrderShopifyDo.getShippingZip());
                    if (stateId <= 8) {//大阪地区优先发货仓库
                        storageId = 12L;
                    } else {//东京仓库优先发货仓库
                        storageId = 10L;
                    }
                    // LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper<>();
                    // wrapper1.eq(StockRecordDo::getShopId, res.getShopId())
                    //         .eq(StockRecordDo::getProductInfoId, productId)
                    //         .eq(StockRecordDo::getStorageId, storageId);
                    // StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                    // if (stockRecordDo == null) {
                    //     failedItems.add(itemsDo);
                    //     continue;
                    // }
                    // int noDeliveredCount = stockDao.getOrderOutCount(productId, res.getShopId(), storageId)
                    //         + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageId);
                    int count = itemsDo.getCount();
                    int canUseCount = stockRecordService.getStockCount(res.getCompanyId(), res.getShopId(), storageId, productId, count);
                    if (canUseCount < count) {//优先仓库有库存，优先仓库发货
                        failedItems.add(itemsDo);
                        continue;
                    }
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setOrderId(itemsDo.getOrderId());
                    productDetail.setProductId(productId);
                    productDetail.setCount(count);
                    orderOutputProductDetailList.add(productDetail);
                }
                OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                packageDetail.setProductList(orderOutputProductDetailList);
                OrderOutputAddReq addReq = new OrderOutputAddReq();
                BeanUtils.copyProperties(res, addReq);
                addReq.setCod(0);
                packageAddReqList.add(packageDetail);
                addReq.setStorageId(storageId);
                addReq.setPackageList(packageAddReqList);
                //默认仓库库存不足
//                if (failedItems.size() < 1 && storageId != 0) {
                if (failedItems.size() != itemAddReqList.size() && storageId != 0) {
                    if (itemAddReqList.size() > failedItems.size()) {
                        addReq.setCod(res.getCod());
                        isSetCod = true;
                    }
                    orderOutputAddReqList.add(addReq);
                } //一个仓库是否发完所有订单
                if (failedItems.size() > 0) {
                    List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                    //剩余一件商品无库存
                    if (failedItems.size() == 1 && failedItems.get(0).getCount() == 1) {
                        storageId = 0L;
                        Long productId = getProductId(failedItems.get(0).getCommoditySku(), res.getCompanyId());
                        List<StorageDo> storageDos = storageDao.selectList(null);
                        int count = failedItems.get(0).getCount();
                        for (StorageDo storageDo : storageDos) {//遍历仓库是否都有库存
                            // LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper<>();
                            // wrapper2.eq(StockRecordDo::getShopId, res.getShopId())
                            //         .eq(StockRecordDo::getProductInfoId, productId)
                            //         .eq(StockRecordDo::getStorageId, storageDo.getId());
                            // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                            size = shipPriceService.countSameSkuSize(new double[4], productId, count);
                            // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId())
                            //         + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                            int canUseCount = stockRecordService.getStockCount(res.getCompanyId(), res.getShopId(), storageDo.getId(), productId, count);
                            if (canUseCount >= count) {
                                List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(res.getPostCode(),
                                        size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                                if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) {
                                    continue;
                                }
                                if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                    shipPirce = shipPriceDos.get(0).getPrice();
                                    storageId = storageDo.getId();
                                }
                            }
                        }
                        OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                        productDetail.setProductId(productId);
                        productDetail.setCount(count);
                        productAddList.add(productDetail);
                        OrderOutputPackageAddReq packageDetail1 = new OrderOutputPackageAddReq();
                        if (storageId != 0) {
                            List<OrderOutputPackageAddReq> packageAddReqList1 = new ArrayList<>();
                            packageDetail1.setProductList(productAddList);
                            OrderOutputAddReq addReq1 = new OrderOutputAddReq();
                            BeanUtils.copyProperties(res, addReq1);
                            if (!isSetCod) {
                                addReq1.setCod(res.getCod());
                                isSetCod = true;
                            } else {
                                addReq1.setCod(0);
                            }
                            packageAddReqList1.add(packageDetail1);
                            addReq1.setStorageId(storageId);
                            addReq1.setPackageList(packageAddReqList1);
//                            if (orderCount > 0) addReq.setOrderNo(addReq.getOrderNo() + "-" + orderCount);
//                            orderCount++;
                            orderOutputAddReqList.add(addReq1);
                        } else {
                            failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_STOCK_ID, OrderShopifyDo.getOrderNumber(), failedItems.get(0).getCommoditySku()));
                        }
                    } else {
                        List<OrderOutputProductAddReq> productAddList1 = new ArrayList<>();
                        //多件商品无库存，第二优先捆包
                        List<OrderOutputProductAddReq> productDoListFailed = new ArrayList<>();
                        List<OrderOutputProductAddReq> productDoListSuccess = new ArrayList<>();
                        LambdaQueryWrapper<StorageDo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper.eq(StorageDo::getSupportShip, 1)
                                .ne(StorageDo::getId, storageId);
                        if (stateId <= 7) {
                            lambdaQueryWrapper.orderByDesc(StorageDo::getStorageArea);
                        } else {
                            lambdaQueryWrapper.orderByAsc(StorageDo::getStorageArea);
                        }
                        List<StorageDo> storageDos = storageDao.selectList(lambdaQueryWrapper);
                        storageId = 0L;
                        if (storageDos != null) {
                            kk:
                            for (StorageDo storageDo : storageDos) {
                                //遍历支持捆包仓库是否都有库存
                                for (OrderOutputProductAddReq productDo :
                                        failedItems) {
                                    Long productId = getProductId(productDo.getCommoditySku(), res.getCompanyId());
                                    int count = productDo.getCount();
                                    if (count < 1) {
                                        count = productDo.getCount();
                                    }
                                    // LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper<>();
                                    // wrapper1.eq(StockRecordDo::getShopId, res.getShopId())
                                    //         .eq(StockRecordDo::getProductInfoId, productId)
                                    //         .eq(StockRecordDo::getStorageId, storageDo.getId());
                                    // StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                                    // if (stockRecordDo == null) {
                                    //     productDoListSuccess.clear();
                                    //     productAddList1.clear();
                                    //     productDoListFailed.clear();
                                    //     productDoListFailed.addAll(failedItems);
                                    //     continue kk;
                                    // }
                                    // int noDeliveredCount = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId())
                                    //         + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                                    int canUseCount = stockRecordService.getStockCount(res.getCompanyId(), res.getShopId(), storageDo.getId(), productId, count);
                                    if (canUseCount < count) {
                                        productDoListSuccess.clear();
                                        productAddList1.clear();
                                        productDoListFailed.clear();
                                        productDoListFailed.addAll(failedItems);
                                        continue kk;
                                    } else {
                                        productDoListSuccess.add(productDo);
                                    }
                                    storageId = storageDo.getId();
                                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                    productDetail.setProductId(productId);
                                    productDetail.setCount(count);
                                    productAddList1.add(productDetail);
                                }
                                if (productDoListSuccess.size() == failedItems.size()) {
                                    productDoListSuccess.clear();
                                    productDoListFailed.clear();
                                    packageDetail = new OrderOutputPackageAddReq();
                                    List<OrderOutputPackageAddReq> packageAddReqList1 = new ArrayList<>();
                                    packageDetail.setProductList(productAddList1);
                                    OrderOutputAddReq addReq1 = new OrderOutputAddReq();
                                    BeanUtils.copyProperties(res, addReq1);
                                    if (!isSetCod) {
                                        addReq1.setCod(res.getCod());
                                        isSetCod = true;
                                    } else {
                                        addReq1.setCod(0);
                                    }
                                    packageAddReqList1.add(packageDetail);
                                    if (storageId != 0) {
                                        addReq1.setStorageId(storageId);
                                        addReq1.setPackageList(packageAddReqList1);
                                        orderOutputAddReqList.add(addReq1);
                                        break kk;
                                    }
                                } else {
                                    productDoListSuccess.clear();
                                    productAddList1.clear();
                                    productDoListFailed.addAll(failedItems);
                                    continue kk;
                                }
                            }
                        } else {
                            productDoListFailed.addAll(failedItems);
                        }
                        List<OrderOutputProductAddReq> productAddList2;
                        //所有捆包仓库无库存的产品
                        if (productDoListFailed.size() > 0) {//捆包仓库无库存，分别发
                            LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper<>();
                            queryWrapper.eq(StorageDo::getCountryType, 1);
                            List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
                            for (OrderOutputProductAddReq productDo :
                                    productDoListFailed) {
                                storageId = 0L;
                                shipPirce = 99999D;
                                Long productId = getProductId(productDo.getCommoditySku(), res.getCompanyId());
                                int count = productDo.getCount();
                                if (count < 1) {
                                    count = productDo.getCount();
                                }
                                for (StorageDo storageDo : storageDoList) {
                                    //遍历仓库是否都有库存
                                    size = shipPriceService.countSameSkuSize(new double[4], productId,
                                            1);
                                    // wrapper2.eq(StockRecordDo::getShopId, res.getShopId())
                                    //         .eq(StockRecordDo::getProductInfoId, productId)
                                    //         .eq(StockRecordDo::getStorageId, storageDo.getId());
                                    // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                                    // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId())
                                    //         + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                                    int canUseCount = stockRecordService.getStockCount(res.getCompanyId(), res.getShopId(), storageDo.getId(), productId, count);
                                    if (canUseCount >= count) {
                                        List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(res.getPostCode(),
                                                size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                                        if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) {
                                            continue;
                                        }
                                        if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                            shipPirce = shipPriceDos.get(0).getPrice();
                                            storageId = storageDo.getId();
                                        }
                                    }
                                }
                                if (storageId != 0) {
                                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                    productAddList2 = new ArrayList<>();
                                    productDetail.setProductId(productId);
                                    productDetail.setCount(count);
                                    productAddList2.add(productDetail);
                                    packageDetail = new OrderOutputPackageAddReq();
                                    packageAddReqList = new ArrayList<>();
                                    packageDetail.setProductList(productAddList2);
                                    addReq = new OrderOutputAddReq();
                                    BeanUtils.copyProperties(res, addReq);
                                    if (!isSetCod) {
                                        addReq.setCod(res.getCod());
                                        isSetCod = true;
                                    } else {
                                        addReq.setCod(0);
                                    }
                                    packageAddReqList.add(packageDetail);
                                    addReq.setStorageId(storageId);
                                    addReq.setPackageList(packageAddReqList);
//                                if (orderCount > 0) addReq.setOrderNo(addReq.getOrderNo() + "-" + orderCount);
//                                orderCount++;
                                    orderOutputAddReqList.add(addReq);
                                } else {
                                    //剩余SKU都没有库存
                                    failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_STOCK_ID, OrderShopifyDo.getOrderNumber(), productDo.getCommoditySku()));
                                }
                            }
                        }
                    }
                }
            }
            if (orderOutputAddReqList.size() > 0) {
                // operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, OrderShopifyDo.getId(), userId, 7);

            }
        }
        long lastStorageId = 0;
        String lastOrderNo = "";
        List<OrderOutputAddReq> orderOutputFinalAddReqList = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList.stream()
                .sorted((o1, o2) -> (int) (o1.getStorageId() - o2.getStorageId()))
                .collect(Collectors.toList())) {
            StringBuilder sku = new StringBuilder();
            int cout = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                cout = cout + orderOutputProductAddReq.getCount();
                if (StringUtils.isNotBlank(sku.toString())) {
                    sku.append(",");
                }
                sku.append(productInfoService.getById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(cout);

            if (lastStorageId == outputAddReq.getStorageId() && lastOrderNo.equals(outputAddReq.getOrderNo())) {
                orderOutputFinalAddReqList.get(orderOutputFinalAddReqList.size() - 1).getPackageList().get(0).getProductList().addAll(outputAddReq.getPackageList().get(0).getProductList());
                orderOutputFinalAddReqList.get(orderOutputFinalAddReqList.size() - 1).setSku(orderOutputFinalAddReqList.get(orderOutputFinalAddReqList.size() - 1).getSku() + "," + sku);
                orderOutputFinalAddReqList.get(orderOutputFinalAddReqList.size() - 1).setCount(orderOutputFinalAddReqList.get(orderOutputFinalAddReqList.size() - 1).getCount() + cout);
            } else {
                orderOutputFinalAddReqList.add(outputAddReq);
            }
            lastStorageId = outputAddReq.getStorageId();
            lastOrderNo = outputAddReq.getOrderNo();
        }
        if (isAuto) {
            sendOutMatch(orderOutputFinalAddReqList, userId);
        }

        Map<String, Object> map = new HashMap<>(8);
        map.put("orderList", orderOutputFinalAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));
        return SingleResult.success(map);
    }

    /**
     * 获取COD代收款的手续费
     *
     * @param orderId
     * @param subtotalPrice
     * @return
     */
    private int getOtherFee(long orderId, double subtotalPrice) {
        LambdaQueryWrapper<OrderShopifyShippingLinesDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderShopifyShippingLinesDo::getOrderId, orderId);
        List<OrderShopifyShippingLinesDo> shippingLinesDos = shippingLinesDao.selectList(wrapper);

        if (subtotalPrice < 10000) {
            return 330;
        } else if (subtotalPrice < 30000) {
            return 440;
        } else if (subtotalPrice < 100000) {
            return 660;
        } else if (subtotalPrice < 300000) {
            return 1100;
        } else if (subtotalPrice < 500000) {
            return 2200;
        } else if (subtotalPrice < 600000) {
            return 6600;
        } else {
            int i = (int) ((subtotalPrice - 600000) / 100000);
            return 6600 + i * 1100;
        }
    }

    @Override
    public SingleResult sendOutNopackage(String id, Long userId, Long companyId) {
        sufficientFundsCheck(companyId);
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        List<OrderOutputProductAddReq> itemAddReqList = new ArrayList<>();
        List<String> failOrders = new ArrayList<>();
        OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
        if (OrderShopifyDo == null) {
            throw new BizExceptionI18(SysConstant.NO_ORDER_INFO_ID, OrderShopifyDo.getOrderNumber());
        }
        if ("Canceled".equals(OrderShopifyDo.getFinancialStatus()) ||
                "refunded".equals(OrderShopifyDo.getFinancialStatus()) ||
                "voided".equals(OrderShopifyDo.getFinancialStatus())) {
            throw new BizExceptionI18(SysConstant.ORDER_HAS_CANCEL_ID, OrderShopifyDo.getOrderName());
        }
        LambdaQueryWrapper<OrderShopifyProductDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderShopifyProductDo::getOrderId, id);
        List<OrderShopifyProductDo> itemsDoList = productDao.selectList(wrapper);
        //订单
        OrderOutputAddReq res = new OrderOutputAddReq();
        res.setOrderType(1);
        if (OrderShopifyDo.getPaymentGatewayNames().contains("代金引換") ||
                OrderShopifyDo.getPaymentGatewayNames().contains("代金引换") ||
                OrderShopifyDo.getPaymentGatewayNames().contains("Cash on Delivery (COD)")) {
            res.setCod((int) OrderShopifyDo.getSubtotalPrice() + getOtherFee(OrderShopifyDo.getId(), OrderShopifyDo.getSubtotalPrice()));
        } else if ((!"authorized".equals(OrderShopifyDo.getFinancialStatus()) &&
                !"partially_refunded".equals(OrderShopifyDo.getFinancialStatus()) &&
                !"paid".equals(OrderShopifyDo.getFinancialStatus()))) {
            if (!OrderShopifyDo.getPaymentGatewayNames().contains("B2B")) {
                System.out.println("B2B 订单不考虑付款");
                throw new BizExceptionI18(SysConstant.ORDER_NO_PAYMENT_ID, OrderShopifyDo.getOrderName());
            }
        }
        //订单
        res.setOrderType(1);
        res.setPlatform("shopify");
        res.setPlatformNumber(OrderShopifyDo.getId() + "");
        if (OrderShopifyDo.getPaymentGatewayNames().contains("代金引換") ||
                OrderShopifyDo.getPaymentGatewayNames().contains("代金引换") ||
                OrderShopifyDo.getPaymentGatewayNames().contains("Cash on Delivery (COD)")) {
            res.setCod((int) OrderShopifyDo.getSubtotalPrice());
        } else if ((!"authorized".equals(OrderShopifyDo.getFinancialStatus()) &&
                !"paid".equals(OrderShopifyDo.getFinancialStatus()))) {
            if (OrderShopifyDo.getPaymentGatewayNames().contains("B2B")) {

            } else {
                throw new BizExceptionI18(SysConstant.ORDER_NO_PAYMENT_ID, OrderShopifyDo.getOrderName());
            }
        }
        for (OrderShopifyProductDo productDo : itemsDoList) {
            if (productDo.getSku().contains("+")) {
                for (String sku : productDo.getSku().split("\\+")) {
                    OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                    Long productId = productInfoService.getProductId(sku, OrderShopifyDo.getCompanyId());
                    if (productId == null) {
                        failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_INFO2_ID, OrderShopifyDo.getOrderNumber(), sku));
                        continue;
                    }
                    productDo1.setProductId(productId);
                    productDo1.setCommoditySku(sku);
                    productDo1.setCount(productDo.getQuantity());
                    itemAddReqList.add(productDo1);
                }
            } else {
                ProductInfoDo productInfoDo = productInfoService.getProductDo(productDo.getSku(), OrderShopifyDo.getCompanyId());
                if (productInfoDo == null) {
                    failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_INFO2_ID, OrderShopifyDo.getOrderNumber(), productDo.getSku()));
                    continue;
                }
                if (!productInfoDo.getTypeOfProduct().equals(StaticDict.Product_Info_Type.Combination.getValue())) {
                    OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                    productDo1.setProductId(productInfoDo.getId());
                    productDo1.setCommoditySku(productInfoDo.getCommoditySku());
                    productDo1.setCount(productDo.getQuantity());
                    itemAddReqList.add(productDo1);
                } else {
                    LambdaQueryWrapper<ProductCombinationDo> productCombinationWrapper = new LambdaQueryWrapper<>();
                    productCombinationWrapper.eq(ProductCombinationDo::getParentId, productInfoDo.getId());
                    List<ProductCombinationDo> productCombinationDoList = productCombinationService.getBaseMapper().selectList(productCombinationWrapper);
                    for (ProductCombinationDo productCombinationDo : productCombinationDoList) {
                        if (productCombinationDo.getEffective() == 1) {
                            if (productCombinationDo.getEffectBeginTime() == null || productCombinationDo.getEffectEndTime() == null)
                                continue;
                            if (OrderShopifyDo.getCreatedAt().getTime() < productCombinationDo.getEffectBeginTime().getTime()
                                    || OrderShopifyDo.getCreatedAt().getTime() > productCombinationDo.getEffectEndTime().getTime())
                                continue;
                        }
                        OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                        ProductInfoDo productInfoDo1 = productInfoService.getById(productCombinationDo.getChildId());
                        if (productInfoDo1 == null) {
                            failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_GROUP_INFO_ID, OrderShopifyDo.getOrderNumber(), productInfoDo.getCommoditySku()));
                            continue;
                        }
                        productDo1.setProductId(productCombinationDo.getChildId());
                        productDo1.setCommoditySku(productInfoDo1.getCommoditySku());
                        productDo1.setCount(productDo.getQuantity() * productCombinationDo.getCount());
                        itemAddReqList.add(productDo1);
                    }
                }
            }
        }
        LambdaQueryWrapper<OrderShopifyShippingLinesDo> wrapperShippingLines = new LambdaQueryWrapper<>();
        wrapperShippingLines.eq(OrderShopifyShippingLinesDo::getOrderId, id);
        List<OrderShopifyShippingLinesDo> shippingLinesDos = shippingLinesDao.selectList(wrapperShippingLines);
        if (shippingLinesDos != null && shippingLinesDos.size() > 0) {
            for (OrderShopifyShippingLinesDo shippingLinesDo : shippingLinesDos) {
                if (shippingLinesDo.getCode() != null) {
                    if (shippingLinesDo.getCode().contains("お急ぎ便")) {
                        res.setShipmentType(1);
                        break;
                    }
                }
            }
        }
//        res.setStatus(0);
        res.setSendDate(new Date());
        res.setShopId(OrderShopifyDo.getShopId());
        res.setCompanyId(OrderShopifyDo.getCompanyId());
        res.setOrderNo(OrderOutputServiceImpl.SHOPIFY_PREFIX + OrderShopifyDo.getOrderNumber());
        res.setReceiverName(OrderShopifyDo.getShippingName());
        res.setTelPhone(OrderShopifyDo.getShippingPhone());
        res.setPostCode(OrderShopifyDo.getShippingZip());
        res.setArea(OrderShopifyDo.getShippingProvince());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(OrderShopifyDo.getShippingCity())) {
            res.setAddress(OrderShopifyDo.getShippingCity() + OrderShopifyDo.getShippingAddress());
        } else {
            res.setAddress(OrderShopifyDo.getShippingAddress());
        }

        //item
        List<OrderOutputProductAddReq> orderOutputProductDetailList = new ArrayList<>();
        LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper<>();
        List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
        for (OrderOutputProductAddReq productDo :
                itemAddReqList) {
            long storageId = 0L;
            double shipPirce = 99999D;
            int count = productDo.getCount();
            Long productId = getProductId(productDo.getCommoditySku(), res.getCompanyId());
            for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper<>();
                double[] size = shipPriceService.countSameSkuSize(new double[4], productId,
                        1);
                // wrapper2.eq(StockRecordDo::getShopId, res.getShopId())
                //         .eq(StockRecordDo::getProductInfoId, productId)
                //         .eq(StockRecordDo::getStorageId, storageDo.getId());
                // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId())
                //         + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                int canUseCount = stockRecordService.getStockCount(res.getCompanyId(), res.getShopId(), storageDo.getId(), productId, count);

                if (canUseCount >= count) {
                    List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(res.getPostCode(),
                            size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                    if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) {
                        continue;
                    }
                    if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                        shipPirce = shipPriceDos.get(0).getPrice();
                        storageId = storageDo.getId();
                    }
                }
            }
            if (storageId != 0) {
                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                productDetail.setProductId(productId);
                productDetail.setCount(count);
                List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                productAddList.add(productDetail);
                OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                packageDetail.setProductList(productAddList);
                OrderOutputAddReq addReq = new OrderOutputAddReq();
                BeanUtils.copyProperties(res, addReq);
                addReq.setCod(0);
                packageAddReqList.add(packageDetail);
                if (storageId != 0) {
                    addReq.setStorageId(storageId);
                    addReq.setPackageList(packageAddReqList);
                    orderOutputAddReqList.add(addReq);
                }
            } else {
                //剩余SKU都没有库存
                failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_STOCK_ID, OrderShopifyDo.getOrderNumber(), productDo.getCommoditySku()));
            }

        }

        if (orderOutputAddReqList.size() > 0) {
            // operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, OrderShopifyDo.getId(), userId, 7);

        }
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int cout = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                cout = cout + orderOutputProductAddReq.getCount();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(sku)) {
                    sku.append(",");
                }
                sku.append(productInfoService.getById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(cout);
        }
        Map<String, Object> map = new HashMap<>(8);
        map.put("orderList", orderOutputAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));
        return SingleResult.success(map);
    }

    @Override
    public SingleResult sendOutMatch(List<OrderOutputAddReq> orderOutputAddReqList, Long userId) {
        List<String> failOrders = new ArrayList<>(outputService.addShopifyList(orderOutputAddReqList, userId));
//        return SingleResult.success(String.format("成功导出%d个发货单", orderOutputAddReqList.size() - failOrders.size()), failOrders);;
        if (failOrders.size() > 0) {
            return SingleResult.failure("300", SysConstant.EXPORT_OUT_ORDER_SUCCESS_ID, failOrders, orderOutputAddReqList.size() - failOrders.size());
        } else {
            return SingleResult.success(failOrders);
        }
    }

    private void sufficientFundsCheck(Long companyId) {
        if (!companyAccountService.getIsDue(companyId)) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);
        }
    }

    private Long getProductId(String sellerSku, Long companyId) {
        ProductInfoDo productInfoDo = productInfoService.getOne(
                Wrappers.<ProductInfoDo>lambdaQuery()
                        .eq(StringUtils.isNotBlank(sellerSku), ProductInfoDo::getCommoditySku, sellerSku)
                        .eq(Objects.nonNull(companyId), ProductInfoDo::getCompanyId, companyId)
                        .last("limit 1")
        );
        if (Objects.isNull(productInfoDo)) {
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(
                    Wrappers.<ProductSkuMapDo>lambdaQuery()
                            .eq(StringUtils.isNotBlank(sellerSku), ProductSkuMapDo::getSubSku, sellerSku)
                            .eq(Objects.nonNull(companyId), ProductSkuMapDo::getCompanyId, companyId)
                            .last("limit 1")
            );
            if (Objects.isNull(productSkuMapDo)) {
                return null;
            }
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }

    private Long getSubProductId(String sellerSku, Long companyId) {
        ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(
                Wrappers.<ProductSkuMapDo>lambdaQuery()
                        .eq(StringUtils.isNotBlank(sellerSku), ProductSkuMapDo::getSubSku, sellerSku)
                        .eq(Objects.nonNull(companyId), ProductSkuMapDo::getCompanyId, companyId)
                        .last("limit 1")
        );
        if (productSkuMapDo == null) {
            return null;
        }
        return productSkuMapDo.getProductInfoId();
    }

    @Override
    public SingleResult pageInit(Long userId, Long companyId) {
        Map<String, Object> result = new HashMap<>(2);
        List<Map<String, Object>> shopList = new ArrayList<>();
        UserDo userDo = userDao.selectById(userId);
        if (userDo == null) {
            throw new BizExceptionI18(SysConstant.NO_USER_INFO);
        }
        LambdaQueryWrapper<ShopDo> shopWrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(userDo.getShopId())) {
            shopWrapper.eq(ShopDo::getId, userDo.getShopId());
        }
        shopWrapper.eq(ShopDo::getCompanyId, companyId);
//        shopWrapper.eq("platform_id", 12);
        List<ShopDo> shopDoList = shopDao.selectList(shopWrapper);
        if (!CollectionUtils.isEmpty(shopDoList)) {
            for (ShopDo shopDo : shopDoList) {
                Map<String, Object> shopMap = new HashMap<>();
                shopMap.put("id", shopDo.getId());
                shopMap.put("value", shopDo.getShopName());
                shopList.add(shopMap);
            }
        }
        result.put("shopList", shopList);
//        result.put("financialStatusList", getFinancialStatusList());
//        result.put("fulfillmentStatusList", getFulfillmentStatusList());

        return SingleResult.success(result);
    }

    private String getOrderShipTypeStr(String orderType) {
        if (StringUtils.isBlank(orderType)) {
            return StringsUtil.createI18Message("未发货");
        } else {
            return StringsUtil.createI18Message(orderType);
        }
//        if ("shipped".equals(orderType) || "fulfilled".equals(orderType)) {
//            return "已发货";
//        } else if ("partial".equals(orderType)) {
//            return "部分发货";
//        } else if ("unshipped".equals(orderType) || orderType == null) {
//            return "未发货";
//        } else if ("restocked".equals(orderType)) {
//            return "取消发货";
//        }
//        return "";
    }

    private String getOrderStatusStr(String orderStatus) {
//        if ("pending".equals(orderStatus)) {
//            return "等待付款";
//        } else if (orderStatus.equals("authorized")) {
//            return "已授权";
//        } else if (orderStatus.equals("partially_paid")) {
//            return "部分付款";
//        } else if (orderStatus.equals("paid")) {
//            return "已付款";
//        } else if (orderStatus.equals("partially_refunded")) {
//            return "部分退款";
//        } else if (orderStatus.equals("refunded")) {
//            return "已退款";
//        } else if (orderStatus.equals("voided")) {
//            return "已作废";
//        }
//        return "";
        return StringsUtil.createI18Message(orderStatus);
    }


    @Override
    public PageResult getListPage(Map<String, String> map) {
        IPage<OrderShopifyListPage> page = pageInit(map);
        page = dao.pageList(page, map);
        List<OrderShopifyRes> resList = handlerListAfter(page.getRecords());
        return new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
    }

    //查询分页列表之后对列表数据的处理
    private List<OrderShopifyRes> handlerListAfter(List<OrderShopifyListPage> list) {
        List<OrderShopifyRes> result = new ArrayList<>();
        list.forEach(et -> {
            OrderShopifyRes res = new OrderShopifyRes();
            ShopDo shopDo = shopDao.selectById(et.getShopId());
            BeanUtils.copyProperties(et, res);
            res.setFulfillmentStatus(getOrderShipTypeStr(et.getFulfillmentStatus()));
            res.setOrderName(et.getOrderName());
            res.setGateway(et.getPaymentGatewayNames());
            res.setShippingAddress(res.getShippingCity() + res.getShippingAddress());
            res.setFinancialStatus(getOrderStatusStr(et.getFinancialStatus()));
            if (shopDo != null) {
                res.setShopName(shopDo.getShopName());
            }
            List<OrderShopifyProductDo> shopifyProductDos = orderShopifyProductDao.selectList(new LambdaQueryWrapper<OrderShopifyProductDo>()
                    .eq(OrderShopifyProductDo::getOrderId, et.getId()));
            if (shopifyProductDos.size() > 0) {
                List<String> skuList = shopifyProductDos.stream().map(OrderShopifyProductDo::getSku)
                        .collect(Collectors.toList());
                String sku = StringUtils.join(skuList, ",");
                res.setSku(sku);
                result.add(res);
            }
        });
        return result;
    }

    @Override
    public SingleResult webhook(String hmac, String type, String data, HttpServletResponse servletResponse) {
        try {
            if (!HmacUtil.HMACSHA256(data, GlobalConstants.ShopifySecret).equals(hmac)) {
                return SingleResult.failure("鉴权失败", servletResponse);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public SingleResult webhookOrder(String hmac, String type, String body, HttpServletResponse servletResponse) {
        return null;
    }

    private IPage<OrderShopifyListPage> pageInit(Map<String, String> map) {
        IPage<OrderShopifyListPage> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }


    private LambdaQueryWrapper<OrderShopifyDo> queryBuild(OrderShopifyQueryBo bo) {
        LambdaQueryWrapper<OrderShopifyDo> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotBlank(bo.getOrderName()), OrderShopifyDo::getOrderName, bo.getOrderName());
        lqw.like(StringUtils.isNotBlank(bo.getShippingName()), OrderShopifyDo::getShippingName, bo.getShippingName());
        lqw.eq(StringUtils.isNotBlank(bo.getPayState()), OrderShopifyDo::getFinancialStatus, bo.getPayState());
        lqw.eq(StringUtils.isNotBlank(bo.getShopId()), OrderShopifyDo::getShopId, bo.getShopId());
        lqw.eq(Objects.nonNull(bo.getCompanyId()), OrderShopifyDo::getCompanyId, bo.getCompanyId());
        lqw.eq(StringUtils.isNotBlank(bo.getSendState()), OrderShopifyDo::getFulfillmentStatus, bo.getSendState());
        lqw.eq(StringUtils.isNotBlank(bo.getIsSendOut()), OrderShopifyDo::getIsSendOut, bo.getIsSendOut());
        lqw.ge(Objects.nonNull(bo.getStartDate()), OrderShopifyDo::getCreatedAt, bo.getStartDate());
        lqw.le(Objects.nonNull(bo.getEndDate()), OrderShopifyDo::getCreatedAt, bo.getEndDate());
        lqw.orderByDesc(OrderShopifyDo::getNumber);
        return lqw;
    }
}
